const oss = {
  methods: {
    async filter (files) {
      await this.filterSize(files)
      await this.filterType(files)
    },
    // 过滤文件个数
    filterSize (files) {
      return new Promise(resolve => {
        if (this.uploadFiles.length + files.length > this.length) {
          this.$message.warning(`最多只能上传${this.length}个文件`)
        } else {
          resolve()
        }
      })
    },
    // 过滤文件类型
    filterType (files) {
      return new Promise(resolve => {
        if (this.type.length > 0) {
          const defaultType = new Set(this.type)
          let status = false
          for (let i = 0; i < files.length; i++) {
            const file = files[i]
            const last = file.name.lastIndexOf('.')
            let type = file.name.slice(last + 1).toLowerCase()
            if (!defaultType.has(type)) {
              this.$message.warning(`只能上传${[...defaultType.values()]}`)
              status = true
            }
          }
          if (!status) {
            resolve()
          }
        } else {
          resolve()
        }
      })
    },
    continueUpload (files, resolve, target) {
      for (let i = 0; i < files.length; i++) {
        this.uploadFiles.push(this.addFile(files[i], target))
      }
      this.uploadFiles.forEach(file => {
        // 如果是正在上传的文件
        if (file.progress > 0) {
          return
        }
        // 如果是已经上传完成的文件
        if (file.success > 0) {
          return
        }
        this.computeMD5(file).then(() => {
          this.uploadFile(file, resolve)
        })
      })
    },
    // 添加文件属性
    addFile (file, target) {
      let icon = this.setFileIcon(file.name)
      let type = file.type || icon
      if (icon === 'pbim') {
        type = 'pbim'
      }
      return {
        id: Math.random().toString(36).substr(2),
        chunkList: [],
        progress: 0,
        fileKey: '',
        progressMD5: 0,
        speed: 0,
        error: '',
        success: false,
        isPause: false,
        response: {},
        fileList: [],
        doneParts: [],
        policyInf: {},
        blob: this.setFileBold(file),
        fileName: file.name,
        fileSize: file.size,
        fileType: this.setFileType(file),
        fileIcon: icon,
        fileMine: type,
        playTime: file.playTime || '',
        picRadio: file.picRadio || '',
        uuid: this.getNumber(32, file),
        bgColor: this.$IconColor(icon),
        target: target,
        sourceFile: file
      }
    },
    getNumber (num, file) {
      let data = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
      let result = ''
      for (let i = 0; i < num; i++) {
        let r = Math.floor(Math.random() * 62)
        result += data[r]
      }
      let type = file.name.slice(file.name.lastIndexOf('.'))
      return `${result}${type}`
    },
    setFileType (file) {
      const name = file.name.toLowerCase()
      if (/\.(gif|jpg|jpeg|png)$/.test(name)) {
        return 1
      }
      if (/\.(wav|flav|ape|alac|mp3|JPaavG|ogg|opus)$/.test(name)) {
        return 2
      }
      if (/\.(mpeg|avi|mov|asf|wmv|nvai|3gp|ra|ram|mkv|flv|f4v|rmvb|webm|mp4)$/.test(name)) {
        return 3
      }
      return 4
    },
    setFileBold (file) {
      if (file.type.substr(0, 6) === 'image/') {
        const URL = window.URL || window.webkitURL
        if (URL && URL.createObjectURL) {
          return URL.createObjectURL(file)
        }
      }
    },
    setFileIcon (name) {
      return name.slice(name.lastIndexOf('.') + 1).toLowerCase()
    },
    // 计算文件的MD5
    computeMD5 (file) {
      return new Promise((resolve) => {
        let fileReader = new FileReader()
        let blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice
        let sparkChunkSize = 5242880
        let sparkChunks = Math.ceil(file.sourceFile.size / sparkChunkSize)
        let currentChunk = 0
        fileReader.onload = (e) => {
          let spark = new this.$SparkMd5.ArrayBuffer()
          file.progressMD5 = (currentChunk + 1) / sparkChunks * 100
          spark.append(e.target.result)
          currentChunk++
          if (currentChunk < sparkChunks) {
            loadNext()
          } else {
            Object.assign(file, {MD5: spark.end()})
            resolve()
          }
        }
        const loadNext = () => {
          let start = currentChunk * sparkChunkSize
          let end = start + sparkChunkSize >= file.sourceFile.size ? file.sourceFile.size : start + sparkChunkSize
          fileReader.readAsArrayBuffer(blobSlice.call(file.sourceFile, start, end))
        }
        loadNext()
      })
    },
    // 上传文件
    async uploadFile (file, resolve) {
      await this.uploadFileConfig(file)
      await this.fileSts(file)
      this.isUploaded(file, resolve)
    },
    // 获取文件配置
    uploadFileConfig (file) {
      return new Promise(resolve => {
        let data = {
          'subSystem': this.subSystem
        }
        this.$axios({
          method: 'post',
          url: `${this.$site.homeServer}/common/uploadFileConfig.htm`,
          closeSaveRequest: true,
          data: this.$qs.stringify(data, {indices: false})
        }).then(res => {
          if (res.data.errorMsg) {
            this.$message.error(res.data.errorMsg)
          } else {
            Object.assign(file, {fileConfig: res.data})
            resolve()
          }
        })
      })
    },
    fileSts (file) {
      return new Promise(resolve => {
        let data = {
          'form.subSystem': this.subSystem,
          'form.fileOwnerType': this.fileOwnerType,
          'form.fileName': file.fileName,
          'form.fileSize': file.fileSize,
          'form.fileType': file.fileType,
          'form.fileMime': file.fileMine,
          'form.fileMd5': file.MD5,
          'form.picRadio': file.picRadio,
          'form.playTime': file.playTime
        }
        this.$axios({
          method: 'post',
          url: `${this.$site.homeServer}/common/fileSts.htm`,
          closeSaveRequest: true,
          data: this.$qs.stringify(data)
        }).then(res => {
          if (res.data.errorMsg) {
            this.$message.error(res.data.errorMsg)
            file.error = '上传出错'
            file.blob = ''
          } else {
            const {fileList, policyInf} = res.data
            if (fileList[0].fileKey) {
              file.isUploaded = true
            }
            file.fileList = fileList
            file.fileUuid = fileList[0].fileUuid
            file.fileKey = fileList[0].fileKey
            file.policyInf = policyInf
            file.uuid = `${file.fileUuid}.${file.fileIcon.toLowerCase()}`
            Object.assign(file, {fileBody: {
              fileKey: file.uuid,
              fileSize: file.fileSize,
              fileMd5: file.MD5,
              fileId: fileList[0].fileUuid
            }})
            resolve()
          }
        })
      })
    },
    // 是否已经上传
    isUploaded (file, resolve) {
      // 验证MD5 过服务端已经有这个文件
      if (file.isUploaded) {
        file.success = true
        this.already++
        if (resolve) {
          resolve(file)
        }
      } else {
        // 初始化OSS
        this.initOSS(file, resolve)
      }
    },
    initOSS (file, resolve) {
      let region = 'oss-cn-hangzhou'
      if (file.policyInf.endPoint) {
        if (process.env.NODE_TYPE === 'prod') {
          region = file.policyInf.endPoint.match(/https:\/\/(\S*).aliyuncs/)[1]
        } else {
          region = file.policyInf.endPoint.match(/http:\/\/(\S*).aliyuncs/)[1]
        }
      }
      if (window.location.href.includes('countrygarden.com.cn')) {
        region = 'oss-cn-shenzhen'
      }
      file.clientOSS = new this.$OSS({
        region: region,
        accessKeyId: file.policyInf.accessKeyId,
        accessKeySecret: file.policyInf.accessKeySecret,
        stsToken: file.policyInf.securityToken,
        bucket: file.policyInf.bucket,
        timeout: 180000000
      })
      file.clientOSS.initMultipartUpload(file.uuid, file.sourceFile).then(result => {
        this.partUploadOSS(file, result, resolve)
      })
    },
    partUploadOSS (file, result, resolve) {
      let partSize = 50 * 100 * 1024
      file.clientOSS.multipartUpload(file.uuid, file.sourceFile, {
        // checkpoint: {
        //   file: file.sourceFile,
        //   name: file.uuid,
        //   fileSize: file.fileSize,
        //   partSize: partSize,
        //   uploadId: result.uploadId,
        //   doneParts: file.doneParts
        // },
        progress: (p, checkpoint) => {
          file.progress = p * 100
          // file.doneParts = checkpoint.doneParts
        },
        parallel: 20,
        partSize: partSize,
        callback: {
          url: file.fileConfig.callBackUrl,
          body: JSON.stringify(file.fileBody),
          contentType: 'application/json'
        }
      }).then(() => {
        this.already++
        file.success = true
        if (resolve) {
          resolve(file)
        }
      }).catch((e) => {
        file.progress = 0
        if (e.name === 'cancel') {
          file.error = '上传取消'
        } else {
          file.error = 'OSS出错'
        }
      })
    },
    // 取消上传
    cancelUpload (file) {
      // 如果上传成功 就直接删除文件
      if (file.success) {
        this.uploadFiles = this.uploadFiles.filter(item => item.id !== file.id)
        if (this.totalItem) {
          this.totalItem--
          this.already--
        }
        if (file.target) {
          file.target.value = ''
        }
      } else {
        if (file.clientOSS) {
          file.clientOSS.cancel()
        } else {
          this.uploadFiles = this.uploadFiles.filter(item => item.id !== file.id)
          if (file.target) {
            file.target.value = ''
          }
        }
      }
    },
    // 重新上传
    resetUpload (file) {
      file.error = ''
      this.partUploadOSS(file)
    }
  }
}

export default oss
